In many information processing applications, a server application running on a host or server computer in a distributed network provides processing services or functions for client applications running on terminal or workstation computers of the network which are operated by a multitude of users. Common examples of such server applications include software for processing class registrations at a university, travel reservations, money transfers and other services at a bank, and sales at a business. In these examples, the processing services provided by the server application may update databases of class schedules, hotel reservations, account balances, order shipments, payments, or inventory for actions initiated by the individual users at their respective stations.
Often, server applications require coordinating activities on multiple computers, by separate processes on one computer, and even within a single process. For example, a money transfer operation in a banking application may involve updates to account information held in separate databases that reside on separate computers that may be geographically remote. Desirably, groups of activities that form parts of an operation are coordinated so as to take effect as a single indivisible unit of work, commonly referred to as a transaction. In many applications, performing sets of activities as a transaction becomes a business necessity. For example, if only one account is updated in a money transfer operation due to a system failure, the bank in effect creates or loses money for a customer.
A transaction is a collection of actions that conform to a set of properties (referred to as the "ACID" properties) which include atomicity, consistency, isolation, and durability. Atomicity means that all activities in a transaction either take effect together as a unit, or all fail. Consistency means that after a transaction executes, the system is left in a stable or correct state (i.e., if giving effect to the activities in a transaction would not result in a correct stable state, the system is returned to its initial pre-transaction state). Isolation means the transaction is not affected by any other concurrently executing transactions (accesses by transactions to shared resources are serialized, and changes to shared resources are not visible outside the transaction until the transaction completes). Durability means that the effects of a transaction are permanent and survive system failures. For additional background information on transaction processing, see, inter alia, Jim Gray and Andreas Reuter, Transaction Processing Concepts and Techniques, Morgan Kaufmann, 1993.
In many current systems, services or extensions of an operating system referred to as a transaction manager or transaction processing (TP) monitor implement transactions. A transaction is initiated by a client program, such as in a call to a "begin.sub.-- transaction" application programming interface (API) of the transaction monitor. Thereafter, the client initiates activities of a server application or applications, which are performed under control of the TP monitor. The client ends the transaction by calling either a "commit.sub.-- transaction" or "abort.sub.-- transaction" API of the TP monitor. On receiving the "commit.sub.-- transaction" API call, the TP monitor commits the work accomplished by the various server application activities in the transaction, such as by effecting updates to databases and other shared resources. Otherwise, a call to the "abort.sub.-- transaction" API causes the TP monitor to "roll back" all work in the transaction, returning the system to its pre-transaction state.
In systems where transactions involve activities of server applications on multiple computers, a two-phase commit protocol often is used. In general, the two-phase commit protocol centralizes the decision to commit, but gives a right of veto to each participant in the transaction. In a typical implementation, a commit manager node (also known as a root node or transaction coordinator) has centralized control of the decision to commit, which may for example be the TP monitor on the client's computer. Other participants in the transaction, such as TP monitors on computers where a server application performs part of the work in a transaction, are referred to as subordinate nodes. In a first phase of commit, the commit manager node sends "prepare.sub.-- to.sub.-- commit" commands to all subordinate nodes. In response, the subordinate nodes perform their portion of the work in a transaction and return "ready.sub.-- to.sub.-- commit" messages to the commit manager node. When all subordinate nodes return ready.sub.-- to.sub.-- commit messages to the commit manager node, the commit manager node starts the second phase of commit. In this second phase, the commit manager node logs or records the decision to commit in durable storage, and then orders all the subordinate nodes to commit their work making the results of their work durable. On committing their individual portions of the work, the subordinate nodes send confirmation messages to the commit manager node. When all subordinate nodes confirm committing their work, the commit manager node reports to the client that the transaction was completed successfully. On the other hand, if any subordinate node returns a refusal to commit during the first phase, the commit manager node orders all other subordinate nodes to roll back their work, aborting the transaction. Also, if any subordinate node fails in the second phase, the uncommitted work is maintained in durable storage and finally committed during failure recovery.
In the prior transaction processing systems discussed above, transactions are initiated and completed by explicit programming in the client program, such as by calls to the begin.sub.-- transaction, commit.sub.-- transaction and abort.sub.-- transaction APIs of the transaction monitor. This adds to complexity and increases the burden of programming the server application and client program. Specifically, the client program must be programmed to properly initiate and complete a transaction whenever it uses a server application to perform work that requires a transaction (e.g., work which involves multiple database updates that must be completed together as an atomic unit of work). The server application, on the other hand, relies on its clients to properly manage transactions, and cannot guarantee that all client programs properly initiate and complete transactions when using the server application. The server application therefore must be programmed to handle the special case where the client fails to initiate a needed transaction when using the server application.
The requirement of a client program to explicitly initiate and complete transactions can pose further difficulties in programming models in which the server application is implemented as separate software components, such as in object-oriented programming ("OOP" ). In object-oriented programming, programs are written as a collection of object classes which each model real world or abstract items by combining data to represent the item's properties with functions to represent the item's functionality. More specifically, an object is an instance of a programmer-defined type referred to as a class, which exhibits the characteristics of data encapsulation, polymorphism and inheritance. Data encapsulation refers to the combining of data (also referred to as properties of an object) with methods that operate on the data (also referred to as member functions of an object) into a unitary software component (i.e., the object), such that the object hides its internal composition, structure and operation and exposes its functionality to client programs that utilize the object only through one or more interfaces. An interface of the object is a group of semantically related member functions of the object. In other words, the client programs do not access the object's data directly, but must instead call functions on the object's interfaces to operate on the data.
Polymorphism refers to the ability to view (i.e., interact with) two similar objects through a common interface, thereby eliminating the need to differentiate between two objects. Inheritance refers to the derivation of different classes of objects from a base class, where the derived classes inherit the properties and characteristics of the base class.
Object-oriented programming generally has advantages in ease of programming, extensibility, reuse of code, and integration of software from different vendors and (in some object-oriented programming models) across programming languages. However, object-oriented programming models can increase the complexity and thus programming difficulty of the server application where transaction processing requires explicit initiation and completion by client programs. In particular, by encouraging integration of software components from different vendors, an object-oriented programming model makes it more difficult for programmers to ensure that the client program properly initiates and completes transactions involving the server application's work. Components that are integrated to form the server application and client programs may be supplied by programmers and vendors who do not directly collaborate, such that it is no longer possible to enforce proper behavior of other components by knocking on a colleague's door down the hall. In the absence of direct collaboration, the programmers often must carefully program the components to handle cases where transactions are not properly initiated and completed by the components' clients.
The present invention frees component-based server applications from reliance on explicit programming of their clients to properly manage transaction processing by automatically providing a transaction to encompass a server application component's work according to a server application component's transactional expectations. This simplifies programming of server applications, since the server application components need not be programmed to handle special cases where a client program that uses the component fails to initiate a transaction. The task of programming client also is simplified since the client program need not explicitly initiate and complete transactions even for server application components that require transactions.
According to one aspect of the invention, server application components are run in an execution environment under control of a system-provided service. In this execution environment, a transactional attribute is associated with the server application component to indicate its transactional expectations. For example, the transactional attribute of a server application component that performs multiple database updates can be set to indicate a transaction is required. Then, if a client program fails to provide a transaction when using the component, the system service automatically initiates a transaction to encompass the component's work. The system service also automatically ends the transaction after the work in the transaction is complete.
Additional features and advantages of the invention will be made apparent from the following detailed description of an illustrated embodiment which proceeds with reference to the accompanying drawings.